package domain.web.service.impl;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.annotation.PostConstruct;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import process.model.OntoResource;
import process.model.SimpleAnnotation;
import process.module.LevenshteinDistanceAnnotated;
import process.module.OntoQuery;
import domain.web.dao.CategoryDao;
import domain.web.dao.ManufacturerDao;
import domain.web.dao.ProductDao;
import domain.web.model.Category;
import domain.web.model.ProductView;
import domain.web.model.rq.SearchRq;
import domain.web.service.SearchService;

/**
 * @author tvo35
 * 
 */

@Service
public class SearchServiceImpl implements SearchService {

	@Autowired
	private ProductDao productDao;
	@Autowired
	private ManufacturerDao manufacturerDao;
	@Autowired
	private CategoryDao categoryDao;
	
	OntoQuery ontoQuery;
	LevenshteinDistanceAnnotated annotated;

	@PostConstruct
	// --------Remember to remove this----------
	@Override
	public void initialize() {
		ontoQuery = new OntoQuery();
		annotated = new LevenshteinDistanceAnnotated(0.2);

	}

	@Override
	public List<ProductView> search(SearchRq rq) {
		StringBuilder criteria = new StringBuilder();
		Set<OntoResource> ontoResources = getInstancesInByQuery(rq.getContent());
		if (!ontoResources.isEmpty()) {
			Iterator<OntoResource> i = ontoResources.iterator();
			if (i.hasNext()) {
				criteria.append("'")
						.append(OntoQuery.getNameFromUri(i.next().getUri()))
						.append("'");
				while (i.hasNext()) {
					criteria.append(",")
							.append("'")
							.append(OntoQuery.getNameFromUri(i.next().getUri()))
							.append("'");
				}
			}

			StringBuilder manufactorer = new StringBuilder();

			if (ArrayUtils.isNotEmpty(rq.getManufacturer())) {

				for (long j : rq.getManufacturer()) {
					manufactorer.append(j).append(",");

				}

				manufactorer.deleteCharAt(manufactorer.length() - 1);

			}

			return productDao.getViewListByUri(criteria.toString(),
					rq.getPrice(), manufactorer.toString(), "en");
		}

		return null;
	}

	@Override
	public Set<OntoResource> getInstancesInByQuery(String query) {
		query = StringUtils.trim(query);
		List<OntoResource> resources = ontoQuery.getAllClasses();
		List<OntoResource> instances = ontoQuery.getAllInstance();
		List<SimpleAnnotation> annotations = new ArrayList<SimpleAnnotation>();
		Set<OntoResource> resourceSet = new HashSet<OntoResource>();
		Set<OntoResource> instanceSet = new HashSet<OntoResource>();
		for (OntoResource resource : resources) {
			String searchString = OntoQuery.getClearName(resource.getName());
			annotated.annotate(StringUtils.lowerCase(query), annotations,
					resourceSet, StringUtils.lowerCase(searchString),
					searchString, resource);
		}
		
		for (OntoResource resource : instances) {
			String searchString = resource.getName();
			annotated.annotate(StringUtils.lowerCase(query), annotations,
					instanceSet, StringUtils.lowerCase(searchString),
					searchString, resource);
		}

		Set<OntoResource> results = new HashSet<OntoResource>();

		for (OntoResource resource : resourceSet) {
			results.addAll(ontoQuery.getInstanceFromClass(OntoQuery
					.getNameFromUri(resource.getUri())));
		}
		
		for (OntoResource resource : instanceSet) {
			
			results.add(resource);
		}

		return results;
	}

	@Override
	public List<ProductView> searchList(long id) {
		
		Category category = categoryDao.get(id, "vi");
		
		StringBuilder criteria = new StringBuilder();
		List<OntoResource> ontoResources = ontoQuery.getInstanceFromClass(category.getUri());
		if (!ontoResources.isEmpty()) {
			Iterator<OntoResource> i = ontoResources.iterator();
			if (i.hasNext()) {
				criteria.append("'")
						.append(OntoQuery.getNameFromUri(i.next().getUri()))
						.append("'");
				while (i.hasNext()) {
					criteria.append(",")
							.append("'")
							.append(OntoQuery.getNameFromUri(i.next().getUri()))
							.append("'");
				}
			}

			return productDao.getViewListByUri(criteria.toString(), null, null,
					"vi");

		}

		return null;
	}

	public static void main(String[] args) {
		SearchService searchService = new SearchServiceImpl();
		searchService.initialize();
		searchService.getInstancesInByQuery("Tìm Máy giặt");
	}
}
